package com.bpvse;

import java.math.BigInteger;
import java.security.Security;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP160R1Curve;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

//P A B N GX GY这些参数的大小写没有影响

public class CurveInit {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    private static final int CURVE_SIZE = 32; // Example size, should be set accordingly
    private static final BigInteger g_Curve_256_P = new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16);
    private static final BigInteger g_Curve_256_A = new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16);
    private static final BigInteger g_Curve_256_B = new BigInteger("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", 16);
    private static final BigInteger g_Curve_256_N = new BigInteger("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 16);
    private static final BigInteger g_Curve_256_Gx = new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16);
    private static final BigInteger g_Curve_256_Gy = new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16);

    private static final BigInteger g_Curve_160_P = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", 16);
    private static final BigInteger g_Curve_160_A = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", 16);
    private static final BigInteger g_Curve_160_B = new BigInteger("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", 16);
    private static final BigInteger g_Curve_160_N = new BigInteger("0100000000000000000001F4C8F927AED3CA752257", 16);
    private static final BigInteger g_Curve_160_Gx = new BigInteger("4A96B5688EF573284664698968C38BB913CBFC82", 16);
    private static final BigInteger g_Curve_160_Gy = new BigInteger("23A628553168947D59DCC912042351377AC5FB32", 16);

    public static int Curve_Init() {

        ECCurve curve;
        ECPoint G;
        BigInteger p, a, b, n, Gx, Gy;

        if (CURVE_SIZE == 32) {
            p = g_Curve_256_P;
            a = g_Curve_256_A;
            b = g_Curve_256_B;
            n = g_Curve_256_N;
            Gx = g_Curve_256_Gx;
            Gy = g_Curve_256_Gy;
            curve = new SecP256R1Curve();
        } else {
            p = g_Curve_160_P;
            a = g_Curve_160_A;
            b = g_Curve_160_B;
            n = g_Curve_160_N;
            Gx = g_Curve_160_Gx;
            Gy = g_Curve_160_Gy;
            curve = new SecP160R1Curve();
        }

        ECFieldElement fGx = curve.fromBigInteger(Gx);
        ECFieldElement fGy = curve.fromBigInteger(Gy);
        G = curve.createPoint(fGx.toBigInteger(), fGy.toBigInteger());

        // Verify the point is on the curve and has the correct order
        if (!G.isValid()) {
            return -1; // ERR_ECURVE_INIT
        }

        ECPoint nG = G.multiply(n);
        if (!nG.isInfinity()) {
            return -1; // ERR_ECURVE_INIT
        }

        return 0;
    }

    public static void main(String[] args) {
        int result = Curve_Init();
        if (result == 0) {
            System.out.println("Curve initialized successfully");
        } else {
            System.out.println("Error initializing curve");
        }
    }
}
